#!/bin/bash
# this script is released under the gnu general public license 3.0
# check the copying file included with this distribution

# gauge_unsquashfs
# runs unsquashfs, displays output as gauge dialog
# originally taken from manjaro
#
# parameters (required)
#  source: source for unsquashfs
#  destination: destination for unsquashfs
#  msg: message to show
#
# returns 0 on success
# returns $error_cancel=64 on user cancel
# anything else is a real error
# reason: show_dialog() needs a way to exit "cancel"
#
# writes menus and noise to stderr

# TODO:
# find a better solution to remove background process then `killall unsquashfs`

# TODO:
# find a way to pipe output of unsquashfs so background process and temp files are not needed
# somehow piping through awk/sed results in strange delays/buffering which is not shown when tee-ing to /dev/tty8 before
# rant end ;)

# location of other scripts to source
readonly SHAREDIR="$(dirname ${0})" || exit $?

# source common variables, functions and error handling
source "${SHAREDIR}"/common.sh || exit $?

# Trap the killer signals so that we can kill child background processes
trap 'killall unsquashfs;' SIGHUP
# unsquashfs ignores SIGINT ...
trap 'killall unsquashfs;' SIGINT
trap 'killall unsquashfs;' SIGTERM

#####################
## begin execution ##

# check input
check_num_args "$(basename $0)" 3 $# || exit $?
SOURCE="${1}"
DESTINATION="${2}"
MSG="${3}"
LINE=
BLOCKS=
PERCENT=
PERCENTTEMP=
RETGAUGE=
# all unsquashfs output goes to /tmp/unsquashfs.log, which we tail
# into a dialog
touch /tmp/setup-unsquashfs-running
#set the return code to failure so if things race we catch the failure
echo 1 > /tmp/.unsquashfs-retcode

# start background process
(
	echo "unsquashing $(basename $1) ..." > /tmp/unsquashfs.log; \
	echo >> /tmp/unsquashfs.log; \
	# unsquash and output to file used for gauge dialog
	# also write filtered output to $LOG
	unsquashfs -f -d "${DESTINATION}" "${SOURCE}" 2>&1 \
		| tee -a /tmp/unsquashfs.log \
		| tr '\r' '\n' | grep -Ev '[[:blank:]][0-9]+/[0-9]+[[:blank:]]+[0-9]+\%$' >>"${LOG}"
	echo $? > /tmp/.unsquashfs-retcode
	echo >> /tmp/unsquashfs.log
	rm -f /tmp/setup-unsquashfs-running
) &

sleep 1

# read output of unsquashfs every x second and keep piping result to the gauge dialog
(
	PERCENT=0
	while [ -e /tmp/setup-unsquashfs-running ]; do
		# sleep 1
		sleep 0.5
		LINE="$(tail -n1 /tmp/unsquashfs.log)" || exit $?
		PERCENTTEMP="$(echo "${LINE}" | sed -r 's/^.*[[:space:]]([0-9]+)%$/\1/')" || exit $?
		if [[ ${PERCENTTEMP} =~ ${ISNUMBER} ]]; then
			PERCENT="${PERCENTTEMP}"
			BLOCKS="$(echo "${LINE}" | sed -r 's#^.*[[:space:]]+([0-9]+)/([0-9]+)[[:space:]]+.*$#\1 of \2 blocks#')" || exit $?
			echo "${PERCENT}"
			echo "XXX"
			echo "${MSG}"
			echo " => "
			echo "${BLOCKS}"
			echo "XXX"
		else
			echo "XXX"
			echo "${MSG}"
			echo " => "
			echo "Progress Indicator Frozen at ${PERCENT} % (but no errors seen)"
			echo "XXX"
		fi
	done
) |
# prepend dummy values for auto-sizing of dialog
show_dialog --gauge "${MSG} => ......... of ......... blocks" 0 0 0
RETGAUGE=$?
if [ "${RETGAUGE}" -ne 0 ]; then
	echo "User cancelled unsquashfs by exiting gauge dialog." 1>&2
	killall unsquashfs
	exit "${RETGAUGE}"
fi
# check success
while [ -e /tmp/setup-unsquashfs-running ]; do
	echo "Won the race, night night (This should have been impossible)" 1>&2
	sleep 1
done
if ! [ -f /tmp/.unsquashfs-retcode ]; then
	echo "This shouldn't be possible, /tmp/.unsquashfs-retcode is missing" 1>&2
fi
# alert the user to fatal errors
#make sure we have a retcode
if [ -z "$(cat /tmp/.unsquashfs-retcode)" ]; then
	killall unsquashfs
	show_dialog --title "Error unsquashing, no return code" --exit-label \
		"OK" --textbox "/tmp/unsquashfs.log" 18 70
	exit 1
fi
#make sure the retcode is a number
if ! [[ $(cat /tmp/.unsquashfs-retcode) =~ ${ISNUMBER} ]]; then
	killall unsquashfs
	show_dialog --title "Error unsquashing, code '$(cat /tmp/.unsquashfs-retcode)'" --exit-label \
		"OK" --textbox "/tmp/unsquashfs.log" 18 70
	exit 1
fi
#make sure the retcode is 0
if [ $(cat /tmp/.unsquashfs-retcode) -ne 0 ]; then
	killall unsquashfs
	show_dialog --title "Error unsquashing, code '$(cat /tmp/.unsquashfs-retcode)'" --exit-label \
		"OK" --textbox "/tmp/unsquashfs.log" 18 70
	exit 1
fi
# save unsquashfs.log
mv "/tmp/unsquashfs.log" "/tmp/unsquashfs-$(basename "${SOURCE}").log" || exit $?
exit 0
